package com.fqgj.xjd.user.service.impl;

import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.StringUtils;
import com.fqgj.exception.enums.BasicErrorCodeEnum;
import com.fqgj.xjd.user.client.UserLevelService;
import com.fqgj.xjd.user.client.enums.RewardTypeEnum;
import com.fqgj.xjd.user.client.enums.UserRewardEnum;
import com.fqgj.xjd.user.client.request.UserLevelActionRequest;
import com.fqgj.xjd.user.client.request.UserLevelRequest;
import com.fqgj.xjd.user.client.response.UserLevelActionFlow;
import com.fqgj.xjd.user.client.response.UserLevelActionList;
import com.fqgj.xjd.user.client.response.UserLevelInfo;
import com.fqgj.xjd.user.client.response.UserLevelRewardConfig;
import com.fqgj.xjd.user.dao.UserLevelActionFlowDao;
import com.fqgj.xjd.user.dao.UserLevelInfoDao;
import com.fqgj.xjd.user.dao.UserLevelRewardConfigDao;
import com.fqgj.xjd.user.entity.UserLevelActionFlowEntity;
import com.fqgj.xjd.user.entity.UserLevelInfoEntity;
import com.fqgj.xjd.user.entity.UserLevelRewardConfigEntity;
import com.google.common.collect.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @program: cashmama-user
 * @description 用户等级/权益服务
 * @author: frank
 * @create: 2020-04-14 12:03
 **/
@Service("userLevelService")
public class UserLevelServiceImpl implements UserLevelService {

    @Autowired
    private UserLevelInfoDao userLevelInfoDao;
    @Autowired
    private UserLevelRewardConfigDao userLevelRewardConfigDao;
    @Autowired
    private UserLevelActionFlowDao userLevelActionFlowDao;

    @Override
    public Response<Boolean> updateUserLevelInfo(UserLevelRequest request) {
        if(request == null || StringUtils.isEmpty(request.getUserCode())
                || (request.getScore() == null && request.getReward() == null) || request.getType() == null){
            return Response.error(BasicErrorCodeEnum.PARAM_VALID_ERROR, "param invalid");
        }
        if(UserRewardEnum.getByCode(request.getType()) == null){
            return Response.error(BasicErrorCodeEnum.PARAM_VALID_ERROR, "type invalid");
        }
        UserLevelInfoEntity userLevelInfoEntity = userLevelInfoDao.getUserLevelInfoByUserCode(request.getUserCode());
        if(userLevelInfoEntity == null){
            UserLevelInfoEntity entity = new UserLevelInfoEntity()
                    .setCreateDate(new Date())
                    .setLevelCode("0")
                    .setScore(0)
                    .setTotalReward(0)
                    .setUsedReward(0)
                    .setUserCode(request.getUserCode());
            userLevelInfoDao.insert(entity);
        }else{
            if(request.getScore() == 0 && request.getReward() == 0){
                return Response.ok().putData(true);
            }
            Integer usedReward = 0;
            if(request.getRewardType() == RewardTypeEnum.USED_REWARD.getCode()){
                usedReward = request.getReward() < 0 ? -request.getReward() : request.getReward();
            }
            userLevelInfoDao.updateUserLevelInfo(request.getUserCode(), request.getScore(), request.getReward(), usedReward);
        }
        UserLevelActionFlowEntity userLevelActionFlowEntity = new UserLevelActionFlowEntity()
                .setUserCode(request.getUserCode())
                .setCreateDate(new Date())
                .setType(request.getType())
                .setReward(request.getReward() == null ? 0 : request.getReward())
                .setScore(request.getScore() == null ? 0 : request.getScore())
                .setRewardType(request.getRewardType() == null ? 0 : request.getRewardType())
                .setTradeNo(request.getTradeNo());
        userLevelActionFlowDao.insert(userLevelActionFlowEntity);
        return Response.ok().putData(true);
    }

    @Override
    public Response<UserLevelInfo> getUserLevelInfo(String userCode) {
        if(StringUtils.isEmpty(userCode)){
            return Response.error(BasicErrorCodeEnum.PARAM_VALID_ERROR, "userCode cannot be empty");
        }
        UserLevelInfoEntity userLevelInfoEntity = userLevelInfoDao.getUserLevelInfoByUserCode(userCode);

        if(userLevelInfoEntity != null){
            UserLevelInfo userLevelInfo = new UserLevelInfo();
            BeanUtils.copyProperties(userLevelInfoEntity, userLevelInfo);
            return Response.ok().putData(userLevelInfo);
        }else{
            return Response.ok().putData(null);
        }
    }

    @Override
    public Response<List<UserLevelRewardConfig>> queryUserLevelRewardConfig() {
        List<UserLevelRewardConfigEntity> allUserRewardConfigInfo = userLevelRewardConfigDao.getAllUserRewardConfigInfo();
        List<UserLevelRewardConfig> userLevelRewardConfigs = Lists.newArrayList();
        if(CollectionUtils.isNotEmpty(allUserRewardConfigInfo)){
            for(UserLevelRewardConfigEntity entity : allUserRewardConfigInfo){
                UserLevelRewardConfig userLevelRewardConfig = new UserLevelRewardConfig();
                BeanUtils.copyProperties(entity, userLevelRewardConfig);
                userLevelRewardConfigs.add(userLevelRewardConfig);
            }
        }
        return Response.ok().putData(userLevelRewardConfigs);
    }

    @Override
    public Response<List<UserLevelActionFlow>> queryUserLevelActionList(String userCode, Integer type) {
        if(StringUtils.isEmpty(userCode) || type == null){
            return Response.error(BasicErrorCodeEnum.PARAM_VALID_ERROR, "param invalid");
        }
        if(UserRewardEnum.getByCode(type) == null){
            return Response.error(BasicErrorCodeEnum.PARAM_VALID_ERROR, "type invalid");
        }
        List<UserLevelActionFlowEntity> userLevelActionFlowList = userLevelActionFlowDao.getUserLevelActionFlowList(userCode, type);
        List<UserLevelActionFlow> userLevelActionFlows = Lists.newArrayList();
        if(CollectionUtils.isNotEmpty(userLevelActionFlowList)){
            for(UserLevelActionFlowEntity entity : userLevelActionFlowList){
                UserLevelActionFlow userLevelActionFlow = new UserLevelActionFlow();
                BeanUtils.copyProperties(entity, userLevelActionFlow);
                userLevelActionFlows.add(userLevelActionFlow);
            }
        }
        return Response.ok().putData(userLevelActionFlows);
    }

    @Override
    public Response<UserLevelActionList> queryUserLevelActionListByPage(UserLevelActionRequest request) {
        List<UserLevelActionFlowEntity> userLevelActionFlowEntities = userLevelActionFlowDao.getUserLevelActionFlowListByPage(request.getUserCode(), request.getType(), request.getRewardType(), request.getPage());
        if(CollectionUtils.isEmpty(userLevelActionFlowEntities)){
            return Response.ok().putData(new UserLevelActionList());
        }
        List<UserLevelActionFlow> userLevelActionFlowList = Lists.newArrayList();
        for(UserLevelActionFlowEntity entity : userLevelActionFlowEntities){
            UserLevelActionFlow userLevelActionFlow = new UserLevelActionFlow();
            BeanUtils.copyProperties(entity, userLevelActionFlow);
            userLevelActionFlowList.add(userLevelActionFlow);
        }
        UserLevelActionList userLevelActionList = new UserLevelActionList()
                .setUserLevelActionFlowList(userLevelActionFlowList);
        userLevelActionList.setTotalCount(request.getPage().getTotalCount());
        userLevelActionList.setTotalPage(request.getPage().getTotalPage());
        return Response.ok().putData(userLevelActionList);
    }

    @Override
    public Response<List<UserLevelActionFlow>> queryUserLevelActionListByOneWeek(String userCode, Integer type) {
        if(StringUtils.isEmpty(userCode) || type == null){
            return Response.error(BasicErrorCodeEnum.PARAM_VALID_ERROR, "param invalid");
        }
        if(UserRewardEnum.getByCode(type) == null){
            return Response.error(BasicErrorCodeEnum.PARAM_VALID_ERROR, "type invalid");
        }
        Calendar c = Calendar.getInstance();
        int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
        c.add(Calendar.DAY_OF_MONTH, -dayOfWeek);
        c.add(Calendar.DAY_OF_MONTH, 1);
        Date startDate = c.getTime();
        c.add(Calendar.DAY_OF_MONTH, 6);
        Date endDate = c.getTime();
        List<UserLevelActionFlowEntity> userLevelActionFlowList = userLevelActionFlowDao.getUserLevelActionFlowListBetweenDate(userCode, type, startDate, endDate);
        List<UserLevelActionFlow> userLevelActionFlows = Lists.newArrayList();
        if(CollectionUtils.isNotEmpty(userLevelActionFlowList)){
            for(UserLevelActionFlowEntity entity : userLevelActionFlowList){
                UserLevelActionFlow userLevelActionFlow = new UserLevelActionFlow();
                BeanUtils.copyProperties(entity, userLevelActionFlow);
                userLevelActionFlows.add(userLevelActionFlow);
            }
        }
        return Response.ok().putData(userLevelActionFlows);
    }

    @Override
    public Response<List<UserLevelActionFlow>> queryUserLevelActionByUserCodeAndDate(String userCode, Integer type, Date date) {
        if(StringUtils.isEmpty(userCode) || type == null){
            return Response.error(BasicErrorCodeEnum.PARAM_VALID_ERROR, "param invalid");
        }
        if(UserRewardEnum.getByCode(type) == null){
            return Response.error(BasicErrorCodeEnum.PARAM_VALID_ERROR, "type invalid");
        }
        List<UserLevelActionFlowEntity> userLevelActionFlowList = userLevelActionFlowDao.getUserLevelActionFlowListByDate(userCode, type, date);
        List<UserLevelActionFlow> userLevelActionFlows = Lists.newArrayList();
        if(CollectionUtils.isNotEmpty(userLevelActionFlowList)){
            for(UserLevelActionFlowEntity entity : userLevelActionFlowList){
                UserLevelActionFlow userLevelActionFlow = new UserLevelActionFlow();
                BeanUtils.copyProperties(entity, userLevelActionFlow);
                userLevelActionFlows.add(userLevelActionFlow);
            }
        }
        return Response.ok().putData(userLevelActionFlows);
    }
}
